﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace UCF.Core
{
    /// <summary>
    /// 图片帮助类
    /// 生成小图 字符串生成图片 验证码
    /// <para>生成验证码：ImageHelper.Instance.WriteVerifyCode(this);</para>
    /// </summary>
    public class ImageHelper
    {
        /// <summary>
        /// ImageHelper类实例对象
        /// </summary>
        private static ImageHelper instance;
        /// <summary>
        /// 获取ImageHelper实例对象
        /// </summary>
        public static ImageHelper Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ImageHelper();
                    return instance;
                }
                else
                {
                    return instance;
                }
            }
        }

        /// <summary>
        /// 字体名称
        /// </summary>
        public string FontFamilyValue { get; set; }

        /// <summary>
        /// 字体样式
        /// <para>0=Regular 普通文本</para>
        /// <para>1=Bold 加粗文本</para>
        /// <para>2=Italic 倾斜文本</para>
        /// <para>4=Underline 带下划线的文本</para>
        /// <para>8=Strikeout 中间有直线通过的文本</para>
        /// </summary>
        public int FontStyleValue { get; set; }

        /// <summary>
        /// 字体大小
        /// </summary>
        public int FontSizeValue { get; set; }

        /// <summary>
        /// 字体颜色值
        /// <para>长度为3的数组,[0]=red,[1]=green,[2]=blue</para>
        /// </summary>
        public int[] ColorValue { get; set; }

        /// <summary>
        /// 字体颜色名称
        /// </summary>
        public string ColorName { get; set; }

        /// <summary>
        /// 背景色名称
        /// </summary>
        public string BgColorName { get; set; }

        /// <summary>
        /// 背景色值
        /// <para>长度为3的数组,[0]=red,[1]=green,[2]=blue</para>
        /// </summary>
        public int[] BgColorValue { get; set; }

        /// <summary>
        /// 默认构造方法
        /// </summary>
        public ImageHelper()
        {
            this.FontFamilyValue = "Arial";
            this.FontStyleValue = 0;
            this.FontSizeValue = 0;
        }

        /// <summary>
        /// 获取指定文字的图形
        /// </summary>
        /// <param name="s"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public Bitmap GetBitmapForText(string s, int width = 100, int height = 50, float x = 0, float y = 0)
        {
            Bitmap bitMap;
            Graphics gph;
            using (MemoryStream memoStream = new MemoryStream())
            {
                if (this.FontSizeValue == 0)
                {
                    int fontWidth = (int)Math.Round((double)(width / (s.Length + 1)));
                    int fontHeight = (int)Math.Round(height / 1.5);
                    this.FontSizeValue = fontWidth > fontHeight ? fontHeight : fontWidth;
                }
                bitMap = new Bitmap(width + this.FontSizeValue, height);
                gph = Graphics.FromImage(bitMap);
                if (this.BgColorName != null) gph.Clear(Color.FromName(this.BgColorName));
                if (this.BgColorValue != null) gph.Clear(Color.FromArgb(this.BgColorValue[0], this.BgColorValue[1], this.BgColorValue[2]));
                Font font = new Font(FontFamilyValue, this.FontSizeValue, (FontStyle)FontStyleValue);
                Color fontColor = Color.Empty;
                if (this.ColorValue != null) fontColor = Color.FromArgb(this.ColorValue[0], this.ColorValue[1], this.ColorValue[2]);
                if (this.ColorName != null) fontColor = Color.FromName(this.ColorName);
                if (fontColor == Color.Empty) fontColor = Color.White;
                SolidBrush brush = new SolidBrush(fontColor);
                gph.DrawString(s, font, brush, x, y);
                return bitMap;
            }
        }

        /// <summary>
        /// 获取指定文字的图形
        /// </summary>
        /// <param name="s"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public byte[] CreateImageForText(string s, int width = 100, int height = 50, float x = 0, float y = 0)
        {
            MemoryStream mm = new MemoryStream();
            GetBitmapForText(s, width, height, x, y).Save(mm, ImageFormat.Gif);
            return mm.ToArray();
        }

        /// <summary>
        /// 保存指定文字的图形
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="s"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void SaveImageForText(string filename, string s, int width = 100, int height = 50, float x = 0, float y = 0)
        {
            this.GetBitmapForText(s, width, height, x, y).Save(filename);
        }

        /// <summary>
        /// 输出文字图形
        /// </summary>
        /// <param name="response"></param>
        /// <param name="s"></param>
        public void WriteImage(HttpResponse response, string s)
        {
            response.ClearContent();
            response.ContentType = "image/Gif";
            response.BinaryWrite(this.CreateImageForText(s));

        }
        public void WriteImage(HttpResponse response,Stream stm)
        {
            response.ClearContent();
            response.ContentType = "image/Png";
            Bitmap bmp = new Bitmap(64, 64);
            MemoryStream mstm = (MemoryStream)stm;
            bmp.Save(mstm, ImageFormat.Png);
            response.BinaryWrite(mstm.ToArray());
        }

        /// <summary>
        /// 输出验证码,暂时不用
        /// </summary>
        /// <param name="page"></param>
        /// <param name="varName"></param>
        /// <param name="length"></param>
        public void WriteVerifyImage(System.Web.UI.Page page, string varName = "captcha", int length = 4)
        {
            string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
            Random rnd = new Random();
            int[] arrPoint = new int[4] { rnd.Next(0, 62), rnd.Next(0, 62), rnd.Next(0, 62), rnd.Next(0, 62) };
            s = string.Format("{0}{1}{2}{3}", s[arrPoint[0]], s[arrPoint[1]], s[arrPoint[2]], s[arrPoint[3]]);
            System.Web.SessionState.HttpSessionState session = page.Session;
            session["verifyCode"] = s;
            this.WriteImage(page.Response, s);
        }

        /// <summary>
        /// 重设图片大小
        /// </summary>
        /// <param name="filename">图片文件路径</param>
        /// <param name="width">最大宽度</param>
        /// <param name="height">最大高度</param>
        /// <param name="filename2">指定生成的文件路径</param>
        public void ImageResize(string filename, int width, int height, string filename2 = null)
        {
            if (filename == null || filename.IndexOf('.') == -1) return;
            Image img = Image.FromFile(filename);
            int iH = img.Height; int iW = img.Width;

            int iRateW = (int)Math.Round((decimal)(width * 100 / iW));
            int iRateH = (int)Math.Round((decimal)(height * 100 / iH));
            if (iRateW > iRateH)
            {
                iW = iW * iRateH / 100;
                iH = iH * iRateH / 100;
            }
            else
            {
                iW = iW * iRateW / 100;
                iH = iH * iRateW / 100;
            }
            Bitmap bitMap = new Bitmap(iW, iH);
            Graphics gph = Graphics.FromImage(bitMap);

            gph.InterpolationMode = InterpolationMode.High;
            gph.SmoothingMode = SmoothingMode.HighQuality;
            gph.Clear(Color.Transparent);
            gph.DrawImage(img, new Rectangle(0, 0, iW, iH), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
            if (filename2 == null) filename2 = string.Format("{0}\\{1}_{2}v{3}{4}", Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename), iW, iH, Path.GetExtension(filename));
            bitMap.Save(filename2);
            gph.Dispose();
            bitMap.Dispose();
            img.Dispose();

        }

        /// <summary>
        /// 图片变灰色
        /// </summary>
        /// <param name="oldImage"></param>
        /// <returns></returns>
        Image getGreyImage(Image oldImage)
        {
            Bitmap currentBitmap = new Bitmap(oldImage);
            Graphics g = Graphics.FromImage(currentBitmap);
            ImageAttributes ia = new ImageAttributes();
            float[][] colorMatrix = {
                                  new float[]{0.299f,0.299f,0.299f,0,0},
                                  new float[]{0.587f,0.587f,0.587f,0,0},
                                  new float[]{0.114f,0.114f,0.114f,0,0},
                                  new float[]{0,0,0,1,0},
                                  new float[]{0,0,0,0,1},
                                  };
            ColorMatrix cm = new ColorMatrix(colorMatrix);
            ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia);
            g.Dispose();
            return currentBitmap;
        }
        #region 网络上的验证码

        /// <summary>
        /// 第二种验证码
        /// </summary>
        public class CaptchaB : System.Web.SessionState.IRequiresSessionState
        {
            private static CaptchaB instance;
            public static CaptchaB Instance
            {
                get
                {
                    if (instance == null) instance = new CaptchaB();
                    return instance;

                }
            }
            public void WriteCaptcha(string varName = "captcha", int length = 4)
            {
                Web._Response.Response.Expires = 0;
                Web._Response.Response.CacheControl = "no-cache";

                HttpContext.Current.Session[varName] = GenerateCheckCode();
                this.CreateCheckCodeImage(GenerateCheckCode());
            }

            private string GenerateCheckCode()
            {
                int number;
                char code;
                string checkCode = String.Empty;
                System.Random random = new Random();
                for (int i = 0; i < 4; i++)
                {
                    number = random.Next();
                    code = (char)('0' + (char)(number % 10));
                    checkCode += code.ToString();
                }
                return checkCode;
            }

            private void CreateCheckCodeImage(string checkCode)
            {
                if (checkCode == null || checkCode.Trim() == String.Empty) return;

                System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
                Graphics g = Graphics.FromImage(image);

                //生成随机生成器
                Random random = new Random();

                //清空图片背景色
                g.Clear(Color.White);

                //画图片的背景噪音线
                for (int i = 0; i < 44; i++)
                {
                    int x1 = random.Next(image.Width - i);
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);

                    g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
                }

                Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));

                System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);

                g.DrawString(checkCode, font, brush, 2, 2);

                //画图片的前景噪音点
                for (int i = 0; i < 88; i++)
                {
                    int x = random.Next(image.Width);
                    int y = random.Next(image.Height);

                    image.SetPixel(x, y, Color.FromArgb(random.Next()));
                }

                //画图片的边框线
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);

                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
                HttpContext.Current.Response.ClearContent();
                HttpContext.Current.Response.ContentType = "image/PNG";
                HttpContext.Current.Response.BinaryWrite(ms.ToArray());
            }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="frompath"></param>
        /// <param name="topath"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="scaleRate">缩放比例</param>
        /// <param name="quality">JPEG品质</param>
        public void CompressImage(string frompath, string topath, int width = 0, int height = 0, int scaleRate = 0, int quality = 100)
        {
            Image img;
            Bitmap bmp;
            Graphics grap;
            int w, h;
            try
            {
                img = Image.FromFile(frompath);
                if (scaleRate > 0)
                {
                    // 比例
                    w = Convert.ToInt32(img.Width * (Convert.ToDouble(scaleRate) / 100));
                    h = Convert.ToInt32(img.Height * (Convert.ToDouble(scaleRate) / 100));
                }
                else
                {
                    // 固定宽高
                    w = width;
                    h = height;
                    if (w == 0) w = (int)((double)(h / img.Height) * img.Width);
                    if (h == 0) h = (int)(((double)w / img.Width) * img.Height);
                }

                if (w == 0 && h == 0)
                {
                    w = img.Width;
                    h = img.Height;
                }
                bmp = new Bitmap(w, h);
                grap = Graphics.FromImage(bmp);
                grap.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                grap.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                grap.DrawImage(img, new Rectangle(0, 0, w, h));

                // JPEG品质压缩
                if (quality < 100)
                {
                    System.Drawing.Imaging.ImageCodecInfo encoder = GetEncoderInfo("image/jpeg");
                    try
                    {
                        if (encoder != null)
                        {
                            System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters(1);
                            //设置 jpeg 质量为 60
                            encoderParams.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)60);
                            bmp.Save(topath, encoder, encoderParams);
                            encoderParams.Dispose();

                        }
                    }
                    finally { }
                }
                else
                {
                    //获取图片类型  
                    string fileExtension = Path.GetExtension(frompath).ToLower();
                    //按原图片类型保存缩略图片,不按原格式图片会出现模糊,锯齿等问题.  
                    switch (fileExtension)
                    {
                        case ".gif": bmp.Save(topath, System.Drawing.Imaging.ImageFormat.Gif); break;
                        case ".jpg": bmp.Save(topath, System.Drawing.Imaging.ImageFormat.Jpeg); break;
                        case ".bmp": bmp.Save(topath, System.Drawing.Imaging.ImageFormat.Bmp); break;
                        case ".png": bmp.Save(topath, System.Drawing.Imaging.ImageFormat.Png); break;
                    }
                }
                bmp.Dispose();
                img.Dispose();
                grap.Dispose();
            }
            finally { }
        }
        private System.Drawing.Imaging.ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            //根据 mime 类型，返回编码器
            System.Drawing.Imaging.ImageCodecInfo result = null;
            System.Drawing.Imaging.ImageCodecInfo[] encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
            for (int i = 0; i < encoders.Length; i++)
            {
                if (encoders[i].MimeType == mimeType)
                {
                    result = encoders[i];
                    break;
                }
            }
            return result;

        }

    }
}
